package com.carlinfo.userscenter.common.dao.impl;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.carlinfo.userscenter.common.util.DbUtil;
import com.carlinfo.userscenter.common.util.PageInfoUtil;
import com.carlinfo.userscenter.users.pojo.AAdmins;

public class BaseDaoImpl<T>
{
	protected DbUtil dbUtil = DbUtil.getInstance();

	protected T convertFromDb(T t, ResultSet rs) throws SQLException
	{
		Class cla = t.getClass();
		Object returnObj = null;
		try
		{
			returnObj = cla.newInstance();
		} catch (InstantiationException | IllegalAccessException e1)
		{
			e1.printStackTrace();
		}
		Field[] fields = cla.getDeclaredFields();
		for (int i = 0; i < fields.length; i++)
		{
			try
			{
				
				Field field = fields[i];
				String name = field.getName();
				String setName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1, name.length());
				Class fieldTypeClass = field.getType();

				Method setMethod = null;
				Object dbObj = null;

				if (fieldTypeClass == int.class || fieldTypeClass == Integer.class)
				{
					setMethod = cla.getMethod(setName, int.class);
					dbObj = rs.getInt(name);
				} else if (fieldTypeClass == byte.class || fieldTypeClass == Byte.class)
				{
					setMethod = cla.getMethod(setName, byte.class);
					dbObj = rs.getByte(name);
				} else if (fieldTypeClass == double.class || fieldTypeClass == Double.class)
				{
					setMethod = cla.getMethod(setName, double.class);
					dbObj = rs.getDouble(name);
				} else if (fieldTypeClass == String.class)
				{
					setMethod = cla.getMethod(setName, String.class);
					dbObj = rs.getString(name);
				} else if (fieldTypeClass == Date.class)
				{
					setMethod = cla.getMethod(setName, Date.class);
					dbObj = rs.getTimestamp(name);
				}
				if(setMethod != null)
				{				
					setMethod.invoke(returnObj, dbObj);
				}
			} catch (Exception e)
			{
			} 
		}
		return (T) returnObj;
	}

	protected T findOneBase(String sql, List<Object> paramsList, T t)
	{
		PreparedStatement ps = null;
		ResultSet rs = null;
		Connection connection = this.dbUtil.getConnection();
		try
		{
			ps = connection.prepareStatement(sql);			
			int count = 1;		
			for (Iterator iterator = paramsList.iterator(); iterator.hasNext();)
			{
				Object paramObj = (Object) iterator.next();
				ps.setObject(count, paramObj);
				count++;
			}
			rs= ps.executeQuery();
			if (rs.next())
			{
				t = convertFromDb(t, rs);
				return t;
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			this.dbUtil.closeAll(connection, ps, rs);
		}
		return null;
	}

	protected List<T> find(String sql, List<Object> paramList, T t)
	{
		List<T> resultList = new ArrayList<T>();
		PreparedStatement ps = null;
		ResultSet rs = null;
		Connection connection = this.dbUtil.getConnection();
		try
		{
			ps = connection.prepareStatement(sql);
			int count = 1;
			for (Iterator iterator = paramList.iterator(); iterator.hasNext();)
			{
				Object paramObj = (Object) iterator.next();
				ps.setObject(count, paramObj);
				count++;
			}
			rs = ps.executeQuery();
			System.out.println("==查询记录==");
			while (rs.next())
			{
				t = this.convertFromDb(t, rs);
				resultList.add(t);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			this.dbUtil.closeAll(connection, ps, rs);
		}
		return resultList;
	}

	protected List<T> findByPage(PageInfoUtil pageInfoUtil, String sql, List<Object> paramList, T t)
	{
		List<T> resultList = new ArrayList<T>();
		PreparedStatement ps = null;
		ResultSet rs = null;
		Connection connection = this.dbUtil.getConnection();
		try
		{
			if (pageInfoUtil != null)
			{
				System.out.println("==获取总记录数==");
				String fromIndex = "from";
				String orderbyIndex = "order by";
				String countSQL = "select count(*) " + sql.substring(sql.indexOf(fromIndex), sql.indexOf(orderbyIndex));
				System.out.println("==总记录数SQL语句:==" + countSQL);
				ps = connection.prepareStatement(countSQL);
				int count = 1;
				for (Iterator iterator = paramList.iterator(); iterator.hasNext();)
				{
					Object paramObj = (Object) iterator.next();
					ps.setObject(count, paramObj);
					count++;
				}
				rs = ps.executeQuery();
				if (rs.next())
				{
					int totalRecord = rs.getInt(1);
					pageInfoUtil.setTotalRecord(totalRecord);
				}
				rs.close();
				ps.close();

				System.out.println("==分页开始=(发送第二条语句)==");
				sql = sql + " limit ? , ? ";
				paramList.add(pageInfoUtil.getCurrentRecord());
				paramList.add(pageInfoUtil.getPageSize());
			}

			ps = connection.prepareStatement(sql);
			int count = 1;
			for (Iterator iterator = paramList.iterator(); iterator.hasNext();)
			{
				Object paramObj = (Object) iterator.next();
				ps.setObject(count, paramObj);
				count++;
			}
			rs = ps.executeQuery();

			System.out.println("==查询记录==");

			while (rs.next())
			{
				t = this.convertFromDb(t, rs);
				resultList.add(t);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			this.dbUtil.closeAll(connection, ps, rs);
		}
		return resultList;
	}

	protected int executeSqlUpdate(String sql, List<Object> paramsList)
	{
		int res = 0;
		Connection connection = this.dbUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try
		{
			ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			int parameterIndex = 1;
			for (Iterator iterator = paramsList.iterator(); iterator.hasNext();)
			{
				Object paramObj = (Object) iterator.next();
				ps.setObject(parameterIndex, paramObj);
				parameterIndex++;
			}

			res = ps.executeUpdate();
			rs = ps.getGeneratedKeys();

			if (rs.next())
			{
				int id = rs.getInt(1);

				paramsList.add(id);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			this.dbUtil.closeAll(connection, ps, rs);
		}
		return res;
	}
}